from django.urls import reverse_lazy
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, CreateView, UpdateView,DetailView
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page

from markdownx.utils import markdownify
from django_comments.signals import comment_was_posted

from zanhu02.articles.forms import ArticleForm
from zanhu02.articles.models import Articles
from zanhu02.helper import AuthorRequiredMixin
from zanhu02.notifications.views import notification_handler


class ArticleListView(ListView):
    """已发布的文章里列表"""

    model = Articles  # 指明model就不用复写
    paginate_by = 10
    context_object_name = "articles" # 上下文变量
    template_name = "articles/article_list.html"

    def get_context_data(self, *, object_list=None, **kwargs):
        """ 返回文章的标签"""
        context = super(ArticleListView, self).get_context_data()
        context["popular_tags"] = Articles.objects.get_counted_tags()
        return context

    def get_queryset(self):
        """ 已发表的文章"""
        return Articles.objects.get_published()


class DraftListView(ArticleListView):
    """ 草稿箱文章列表"""
    def get_queryset(self):
        return Articles.objects.filter(user=self.request.user).get_drafts()

class ArticleCreateView(LoginRequiredMixin,CreateView):
    """发表文章,表单"""
    model = Articles
    form_class = ArticleForm
    template_name = 'articles/article_create.html'
    message = '您的文章已创建成功!'

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(ArticleCreateView, self).form_valid(form)

    def get_success_url(self):
        # django的消息框架(将消息传递给下一次请求)
        messages.success(self.request,self.message)
        return reverse_lazy("articles:list")

    def get_markdown(self):
        """ 将markdown文本转换成HTML"""
        return markdownify(self.content)


class ArticleDetailView(DetailView):
    model = Articles
    template_name = 'articles/article_detail.html'
    context_object_name = 'article'
    # slug_url_kwarg = 'slug'


@method_decorator(cache_page(60 * 60),name="get")
class ArticleEditView(LoginRequiredMixin,AuthorRequiredMixin,UpdateView):
    """更改文章"""
    model = Articles
    form_class = ArticleForm
    template_name = 'articles/article_update.html'
    message = "您的文章更改成功!"

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(ArticleEditView, self).form_valid(form)

    def get_success_url(self):
        """更改成功过后跳转"""
        messages.success(self.request,self.message)
        return reverse_lazy("articles:article",kwargs={"slug":self.get_object().slug})


def notify_comment(**kwargs):
    """文章有评论时通知作者"""
    actor = kwargs["request"].user  # 评论者
    obj = kwargs["comment"].content_object     # 评论模型类的实例

    # 调用通知管理器
    notification_handler(actor,obj.user,"C",obj)

comment_was_posted.connect(receiver=notify_comment)
